<template>
    <el-card shadow="never">
        <el-button type="success" @click="openDialog()">新增</el-button>
        <el-button type="danger" :disabled="selectIds.length === 0" @click="handleDelete()">删除</el-button
        >
    </el-card>
    <el-table
            :data="tableData"
            v-loading="loading"
            max-height="80vh"
            border
            style="width: 100%"
            table-layout="auto"
            :show-overflow-tooltip="true"
            row-key="id"
            @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" />
        <!-- 表格前后都是通用的，这里要定义自己的列信息  -->
        <el-table-column label="资源名称" prop="resourceName"/>
        <el-table-column label="资源类型" prop="resourceType" :formatter="resourceTypeFormatter"/>
        <el-table-column label="vue菜单访问路径" prop="menuUrl"/>
        <el-table-column label="vue菜单组件" prop="menuComponent"/>
        <el-table-column label="一级菜单跳转地址" prop="redirect"/>
        <el-table-column label="资源权限编码" prop="perms"/>
        <el-table-column label="资源排序" prop="sortNo"/>
        <el-table-column label="菜单图标" prop="menuIcon"/>
        <el-table-column label="是否路由菜单" prop="isRoute" :formatter="isRouteFormatter"/>
        <el-table-column label="是否叶子节点" prop="isLeaf" :formatter="isLeafFormatter"/>
        <el-table-column label="描述" prop="description"/>

        <el-table-column fixed="right" label="操作" width="150">
            <template #default="scope">
                <el-button size="small" @click="openDialog(scope.row.id)"
                >修改</el-button
                >
                <el-button
                        size="small"
                        type="danger"
                        @click="handleDelete(scope.row.id)"
                >删除</el-button
                >
            </template>
        </el-table-column>
    </el-table>
    <!-- 表单弹窗 -->
    <el-dialog
      v-model="dialog.visible"
      :title="dialog.title"
      width="50%"
      @close="closeDialog"
    >
      <el-form
        ref="formRef"
        :model="formData"
        :rules="rules"
        label-width="20%"
      >
        <el-form-item label="父资源" prop="parentId">
          <el-tree-select
              v-model="formData.parentId"
              :data="sysResourceTreeData"
              node-key="id"
              :render-after-expand="false"
              check-strictly
              placeholder="请选择父资源"
          />
<!--          <el-input v-model="formData.parentId" placeholder="请输入父资源" />-->
        </el-form-item>
        <el-form-item label="资源名称" prop="resourceName">
          <el-input v-model="formData.resourceName" placeholder="请输入资源名称" />
        </el-form-item>
        <el-form-item label="资源类型" prop="resourceType">
          <el-select
              v-model="formData.resourceType"
              class="m-2"
              placeholder="Select"
              size="large"
              style="width: 240px"
              @change="resourceTypeChange"
          >
            <el-option label="菜单" :value="0"/>
            <el-option label="按钮" :value="1"/>
          </el-select>
        </el-form-item>
        <el-form-item v-if="formData.resourceType === 0" label="是否路由菜单" prop="isRoute">
          <el-select
              v-model="formData.isRoute"
              class="m-2"
              placeholder="Select"
              size="large"
              style="width: 240px"
              @change='isRouterChange'
          >
            <el-option label="是" :value="1"/>
            <el-option label="不是" :value="0"/>
          </el-select>
        </el-form-item>
        <el-form-item v-if="formData.resourceType === 0" label="菜单访问路径" prop="menuUrl">
            <el-input v-model="formData.menuUrl" placeholder="请输入菜单访问路径" />
        </el-form-item>
        <el-form-item v-if="formData.resourceType === 0" label="菜单组件" prop="menuComponent">
            <el-input v-model="formData.menuComponent" placeholder="请输入vue菜单组件" />
        </el-form-item>
        <el-form-item v-if="formData.isRoute === 1 && (formData.parentId === null || formData.parentId === undefined || formData.parentId === '')" label="redirect地址" prop="redirect">
          <el-input v-model="formData.redirect" placeholder="请输入跳转地址" />
        </el-form-item>
        <el-form-item v-if="formData.resourceType === 0" label="菜单图标" prop="menuIcon">
          <el-input v-model="formData.menuIcon" placeholder="请输入菜单图标" />
        </el-form-item>
        <el-form-item v-if="formData.resourceType === 1" label="资源权限编码" prop="perms">
            <el-input v-model="formData.perms" placeholder="请输入资源权限编码" />
        </el-form-item>
        <el-form-item label="资源排序" prop="sortNo">
            <el-input v-model="formData.sortNo" placeholder="请输入资源排序" />
        </el-form-item>
        <el-form-item label="描述" prop="description">
            <el-input v-model="formData.description" placeholder="请输入描述" />
        </el-form-item>
        </el-form>
        <template #footer>
            <div class="dialog-footer">
                <el-button type="primary" @click="handleSubmit">确 定</el-button>
                <el-button @click="closeDialog">取 消</el-button>
            </div>
        </template>
    </el-dialog>
</template>

<script lang="ts" setup>
    import {reactive, ref, onMounted} from 'vue'
    import {FormInstance} from "element-plus";
    import {QueryParams} from "@/api/system/sysResource/sysResourceType";
    import {SysResource,SysResourceForm} from "@/api/system/sysResource/sysResourceType";
    import {save,removeById,removeByIds,updateById,queryById,getSysResourceTableTree,getMenuTree} from "@/api/system/sysResource/sysResourceApi";
    import {  ElMessage } from "element-plus";

    // 表格数据
    const tableData = ref<SysResource[]>();
    // 加载状态
    const loading = ref(false);
    // 多选的数据ID
    const selectIds = ref<string>('')
    // 新增/修改弹窗
    const dialog = reactive({
        title: "",
        visible: false,
    });

    // 表单数据
    const formData = reactive<SysResourceForm>({
        id:undefined,
        parentId:'',
        resourceName:undefined,
        menuUrl:undefined,
        menuComponent:undefined,
        redirect:undefined,
        resourceType:0,
        perms:undefined,
        sortNo:0,
        menuIcon:undefined,
        isRoute:0,
        isLeaf:0,
        description:undefined,
        delFlag:0,
    });
    const emptyFormData = reactive<SysResourceForm>({
        id:undefined,
        parentId:undefined,
        resourceName:undefined,
        menuUrl:undefined,
        menuComponent:undefined,
        redirect:undefined,
        resourceType:0,
        perms:undefined,
        sortNo:0,
        menuIcon:undefined,
        isRoute:0,
        isLeaf:0,
        description:undefined,
        delFlag:0,
    });

    const sysResourceTreeData = ref<[]>([]);
    // 修改资源类型，为按钮的时候，将菜单选项都重置，否则将按钮选项重置
    const resourceTypeChange = (value: any) => {
      // 这是一个按钮
      if(value === 1){
        formData.isRoute = 0
        formData.redirect = ''
        formData.menuUrl = ''
        formData.menuComponent = ''
        formData.menuIcon = ''
      }else{
        formData.perms = ''
      }
    }
    // 修改是否路由，若是路由，则填写前端组件路径
    const isRouterChange = (value: any)=>{
      if(value == 0){
        formData.menuComponent = ''
        formData.redirect = ''
      }
    }
    // 当资源类型为按钮时，不必填写资路径
    const menUrlValidator = (rule: any, value: any, callback: any) => {
      if(formData.resourceType === 0){
        if(value === '' || value === null){
          callback(new Error("请输入vue菜单访问路径,eg:/system/sysUser"))
        }
      }
      callback()
    }
    // 当菜单确认为路由时，校验component
    const menuComponentValidator = (rule: any, value: any, callback: any) => {
      if(formData.isRoute === 1){
        if(value === '' || value === null){
          callback(new Error("请输入vue组件访问路径,eg:@/views/system/sysUser/Index.vue"))
        }
      }
      callback()
    }
    // 只在资源类型为按钮时校验权限编码
    const permsValidator = (rule: any, value: any, callback: any) => {
      if(formData.resourceType === 1){
        if(value === '' || value === null){
          callback(new Error("请输入按钮权限编码，eg:system:user:add"))
        }
      }
      callback()
    }
    // 只在资源类型为菜单时校验是否路由
    const isRouteValidator = (rule: any, value: any, callback: any) => {
      if(formData.resourceType === 0){
        if(value === '' || value === null){
          callback(new Error("请选择是否路由"))
        }
      }
      callback()
    }
    // 当菜单没有上级，但是标识为路由时骄傲眼，eg:Home页面
    const redirectValidator = (rule: any, value: any, callback: any) => {
      debugger
      if(formData.resourceType === 0 && formData.isRoute === 1 && (formData.parentId === null || formData.parentId === undefined || formData.parentId === '')){
        if(value === '' || value === null){
          callback(new Error("请输入redirect地址"))
        }
      }
      callback()
    }
    // 表单校验规则
    const rules = reactive({
      resourceName: [{ required: true, message: "请输入资源名称", trigger: "blur" }],
      menuUrl: [{ validator: menUrlValidator, trigger: "blur" }],
      menuComponent: [{validator: menuComponentValidator, trigger: "blur" }],
      resourceType: [{ required: true, message: "请输入资源类型", trigger: "blur" }],
      perms: [{ validator: permsValidator, trigger: "blur" }],
      isRoute: [{ validator: isRouteValidator, trigger: "blur" }],
      redirect: [{ validator: redirectValidator, message: "输入redirect地址",trigger: "blur" }]
    });

    const resourceTypeFormatter=(row, column, cellValue)=>{
      return cellValue === 1?'按钮':'菜单'
    }
    const isRouteFormatter=(row, column, cellValue)=>{
      return cellValue === 1?'是':'否'
    }
    const isLeafFormatter=(row, column, cellValue)=>{
      return cellValue === 1?'是':'否'
    }
    // 页面加载
    onMounted(() => {
        //查询表格数据
        handleQuery();
        initSysResourceTree();
    });
    // 查询参数
    const queryFormRef = ref<FormInstance | null>(null);
    const queryParams = reactive<QueryParams>({
        parentId: undefined,
    })

    //删除事件
    const handleDelete = (id?: any) => {
        if(id){
            removeById(id).then(res=>{
                ElMessage.success("删除成功");
                resetQuery()
            }).finally(() => (loading.value = false));
            return;
        }
        const ids = [selectIds.value].join(",")
        if(!ids){
            ElMessage.error("请选择数据")
            return
        }
        loading.value = true
        removeByIds(ids).then(res=>{
            ElMessage.success("删除成功");
            resetQuery()
        }).finally(() => (loading.value = false));
    }

    // 查询树形数据
    const initSysResourceTree = ()=>{
      getMenuTree().then(res=>{
        sysResourceTreeData.value = res.result
      })
    }
    // 处理多选
    const handleSelectionChange = (val: any) => {
        selectIds.value = val.map((item:any)=>item.id)
    }

    // 处理查询
    function handleQuery() {
      getSysResourceTableTree(queryParams).then(res=>{
            tableData.value = res.result
        })
    }
    // 重置查询表单参数
    function resetQuery() {
        // queryFormRef.value.resetFields();
        handleQuery();
    }

    // 表单引用
    const formRef = ref<FormInstance | null>(null);
    // 打开表单弹窗
    function openDialog(id?: any) {
        dialog.visible = true;
        if (id) {
            dialog.title = "修改资源";
            queryById(id).then(res=>{
                Object.assign(formData, res.result);
            });
        } else {
            dialog.title = "新增资源";
        }
    }
    // 加载下属资源
    const loadSubResource = (row: SysResource,treeNode:unknown,resolve:(data:SysResource[])=>void)=>{
      resolve([])
    }
    // 关闭弹窗
    const closeDialog = ()=>{
        dialog.visible = false;
        resetForm();
    }
    // 重置表单
    const resetForm = ()=>{
        formRef.value.resetFields();
        formRef.value.clearValidate();
        Object.assign(formData, emptyFormData)
    }
    // 提交表单
    const handleSubmit = ()=>{
        formRef.value.validate((valid: any) => {
            if (valid) {
                loading.value = true;
                if (formData.id) {
                    updateById(formData).then(() => {
                        ElMessage.success("修改成功");
                        closeDialog();
                        resetQuery();
                    }).finally(() => (loading.value = false));
                } else {
                    save(formData).then(() => {
                        ElMessage.success("新增成功");
                        closeDialog();
                        resetQuery();
                    }).finally(() => (loading.value = false));
                }
            }
        });
    }
</script>
